package com.ibeeking.found.upms.s.rest.service.impl;

import com.ibeeking.found.common.entity.CurrentUser;
import com.ibeeking.found.common.enums.FrontendTypeEnum;
import com.ibeeking.found.upms.api.common.dto.PermissionDTO;
import com.ibeeking.found.upms.api.feign.UpmsGClient;
import com.ibeeking.found.upms.s.rest.service.IShopPermissionService;
import com.ibeeking.found.upms.s.rest.service.IShopRolePermissionService;
import com.ibeeking.found.upms.s.rest.service.IShopRoleService;
import com.ibeeking.found.upms.s.rest.service.IShopUserRoleService;
import com.ibeeking.found.upms.service.common.bo.ShopPermissionBO;
import com.ibeeking.found.upms.service.common.bo.ShopRolePermissionBO;
import com.ibeeking.found.upms.service.common.bo.ShopUserRoleBO;
import com.ibeeking.found.upms.service.common.constants.RedisKeyConstant;
import com.ibeeking.found.upms.service.common.dos.ShopPermissionDO;
import com.ibeeking.found.upms.service.common.vo.CurrentPermissionVO;
import com.ibeeking.found.upms.service.common.vo.PermissionTreeVO;
import com.ibeeking.found.upms.service.mapper.ShopPermissionMapper;
import com.ibeeking.nematos.redis.utils.RedisUtils;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.data.TreeFastUtils;
import com.ibeeking.nematos.utils.json.JsonUtils;
import com.ibeeking.nematos.utils.result.ResponseResult;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName ShopPermissionServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-02-22 13:37
 **/
@Service
public class ShopPermissionServiceImpl implements IShopPermissionService {

    @Resource
    private ShopPermissionMapper shopPermissionMapper;
    @Resource
    private IShopRoleService roleServiceImpl;
    @Resource
    private IShopUserRoleService userRoleServiceImpl;
    @Resource
    private IShopRolePermissionService rolePermissionServiceImpl;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private UpmsGClient upmsGClient;

    @Override
    public List<ShopPermissionBO> selectAllList() {
        List<ShopPermissionDO> shopPermissionDos = shopPermissionMapper.selectList(Wrappers.emptyWrapper());
        if (Collections3.isEmpty(shopPermissionDos)) {
            return Collections3.emptyList();
        }
        ResponseResult<List<PermissionDTO>> responseResult = upmsGClient.queryAllList(Arrays.asList(FrontendTypeEnum.SHOP.getCode()));
        if (null == responseResult || Collections3.isEmpty(responseResult.getData())) {
            return Collections3.emptyList();
        }
        List<PermissionTreeVO> permissionTreeVos = JsonUtils.jsonToList(responseResult.getData(), PermissionTreeVO.class);
        responseResult = null;
        List<Long> haveIds = shopPermissionDos.stream().map(ShopPermissionDO::getId).collect(Collectors.toList());
        List<Long> resultIds = new ArrayList<>();
        TreeFastUtils.selectLongPidByCid(resultIds, permissionTreeVos, haveIds);
        resultIds.addAll(haveIds);
        List<PermissionTreeVO> collect = permissionTreeVos.stream().filter(s -> resultIds.contains(s.getId())).collect(Collectors.toList());
        return JsonUtils.jsonToList(collect, ShopPermissionBO.class);
    }

    @Override
    public List<CurrentPermissionVO> queryEffectiveList(CurrentUser currentUser, String jti) {
        List<CurrentPermissionVO> result;
        //1 从缓存中查询
        //从缓存中查询用户权限
        Object o = redisUtils.get(RedisKeyConstant.MODULE_S + RedisKeyConstant.USER_PERMISSION + currentUser.getCurrentShop().getShopId() + currentUser.getId() + ":" + jti);
        if (null != o) {
            result = JsonUtils.jsonToList(o, CurrentPermissionVO.class);
        } else {
            //3 根据当前登录用户获取拥有的角色
            List<ShopUserRoleBO> shopUserRoleBos = userRoleServiceImpl.queryRoleIdsByUserId(currentUser.getCurrentShop().getShopId(), currentUser.getId());
            if (Collections3.isEmpty(shopUserRoleBos)) {
                return Collections3.emptyList();
            }
            List<Long> roleIds = shopUserRoleBos.parallelStream().map(ShopUserRoleBO::getRoleId).collect(Collectors.toList());
            // 查询管理员角色id
            Long administratorId = roleServiceImpl.selectAdministratorId();
            boolean administrator = roleIds.contains(administratorId);
            //查询商户所有权限菜单
            List<ShopPermissionBO> shopPermissionBos = selectAllList();
            if (Collections3.isEmpty(shopPermissionBos)) {
                return Collections3.emptyList();
            }
            result = JsonUtils.jsonToList(shopPermissionBos, CurrentPermissionVO.class);

            if (!administrator) {
                //4 根据角色查询权限
                List<ShopRolePermissionBO> shopRolePermissionBos = rolePermissionServiceImpl.queryRolePermissionByRoleIds(currentUser.getRoleIds());
                if (Collections3.isEmpty(shopRolePermissionBos)) {
                    return Collections3.emptyList();
                }
                List<Long> currentIds = shopRolePermissionBos.parallelStream().map(ShopRolePermissionBO::getPermissionId).distinct().collect(Collectors.toList());

                //5 根据权限查询所有上级权限
                List<Long> resultIds = new ArrayList<>();
                TreeFastUtils.selectLongPidByCid(resultIds, result, currentIds);
                resultIds.addAll(currentIds);
                result = result.stream().filter(currentPermissionVO -> resultIds.contains(currentPermissionVO.getId())).collect(Collectors.toList());
            }
            if (!Collections3.isEmpty(result)) {
                //7 存入缓存
                redisUtils.set(RedisKeyConstant.MODULE_S + RedisKeyConstant.USER_PERMISSION + currentUser.getCurrentShop().getShopId() + currentUser.getId() + ":" + jti, result, RedisKeyConstant.HALF_DAY);
            }
        }
        //8 转换数据格式并返回
        return result;
    }
}
